add_library('net')
add_library('sound')
from bot_util import *
w, h = 600, 520
i = 0
bubble_log = {}
brick_log = {}
bubble_time = {}
bubble_power = {}
boom_range = {}
boom_log = {}
exptime = 500
endtime = 1000
bots = []
game = {}
game['bubbles'] = []

img_brick = {}
img_object = {}

position_brick = {}
position_brick['gongfu'] = []
position_brick['box'] = []
position_object = {'number': [], 'speed': [], 'power': []}
c = Client(this, '127.0.0.1',12345)
def get_player_topleft(img, footx, footy):
    return footx - img.width * 0.5, footy - img.height + 20
def get_p1_img(bot):
    global player1_img
    dir = bot['player_state']['current_direction']
    walk_img_i = get_bot_walk_img_i(bot)
    return player1_img[dir][walk_img_i]
def get_p2_img(bot):
    global player2_img
    dir = bot['player_state']['current_direction']
    walk_img_i = get_bot_walk_img_i(bot)
    return player2_img[dir][walk_img_i]
def add_bot_mile(bot,s):
    bot['player_state']['s']+=s
    
def get_bot_mile(bot):
    return bot['player_state']['s']

def get_bot_walk_img_i(bot):
    s = get_bot_mile(bot)
    s = int(s/8)
    return s%4
def new_bot():
    global i
    global position_brick
    p = PVector(w - 200, 100)
    #bricks = position_brick['gongfu']
    d = {'id': i, 'position': p, 'state': 'alive', 'target': None, 'bubbles': [], 'player_state':new_player_state()}
 
    i += 1
    return d        
def get_speed(d):
    return   4

def brick_bubble_player_limit(pp, direction,v):
    c, r = get_grid_idx(pp.x, pp.y)
    forbids = game['bubbles'] + position_brick['gongfu'] + position_brick['box']
    dir2dxdy = {'left':(-1,0),'right':(1,0),'up':(0,-1),'down':(0,1)}
    dx,dy = dir2dxdy[direction]
    if (c+dx,r+dy) in forbids:
        if dx+dy >0:fun = min
        if dx+dy < 0 : fun = max
        if direction in ['left','right']:
            pp.x = fun(grid_w * (c + 0.5)   , pp.x+ dx*v)
        else:
            pp.y = fun(grid_h * (r + 0.5)   , pp.y+ dy*v)
    else:
        pp.x = pp.x+ dx*v
        pp.y =  pp.y+ dy*v
    return pp
def bot_walk(bot,current_direction):
    bot['player_state']['current_direction'] = current_direction#['left','right','up','down'][r]
    v = get_speed(bot['player_state']) 
    dirs = ['left', 'right', 'up', 'down']
    
    r = dirs.index(current_direction)
    
    ds = [(-v, 0), (v, 0), (0, -v), (0, v)]
    dx, dy = ds[int(r)]
    add_bot_mile(bot,v)
    pp = bot['position']
   
    pp = brick_bubble_player_limit(pp, dirs[int(r)],v)
    bot['position'] = pp
    #bot['position'].x, bot['position'].y = pp.x+dx,pp.y+dy
    #bot['position'].x, bot['position'].y = limit_player(bot['position'].x, bot['position'].y)
    print(pp)       
    return bot
def draw_map():
    for x, y in position_brick['gongfu']:
        y, x = get_grid_topleft(y, x)
        image(img_brick['gongfu'], x, y)
def setup():
    size(780, h + 65)
    frameRate(60)
    background(204)
    stroke(0)
    
    img_object['number'] = loadImage('number.png')
    img_object['power'] = loadImage('power.png')
    img_object['speed'] = loadImage('speed.png')
    global obj_voice
    obj_voice = SoundFile(this, 'getobj.wav')
    
    
    global boom
    boom = loadImage('mid_boom.png')
    global bubble_img
    bubble_img = loadImage('bomb3.png')
    global bg_img
    bg_img = loadImage('land.jpg')
    global player2_img
    player2_img= {'left': [], 'right': [], 'up': [], 'down': []}            
    for direction in player2_img.keys():
        for i in range(4):
            directioni = {'left':1,'right':2,'up':3,'down':0}.get(direction)
            img = loadImage('walk_54_{}_{}.png'.format(directioni, i))
            player2_img[direction].append(img)
    global player2
    player2 = new_bot()
    
    
    global player1_img
    player1_img= {'left': [], 'right': [], 'up': [], 'down': []}            
    for direction in player1_img.keys():
        for i in range(4):
            directioni = {'left':1,'right':2,'up':3,'down':0}.get(direction)
            img = loadImage('walk_15_{}_{}.png'.format(directioni, i))
            player1_img[direction].append(img)
    global player1
    player1 = new_bot()
    
    bots = [player1,player2]
    img_brick['gongfu'] = loadImage('gongfu.jpeg')
    img_brick['box'] = loadImage('box.jpg')
    img_object['number'] = loadImage('number.png')
    img_object['power'] = loadImage('power.png')
    img_object['speed'] = loadImage('speed.png')
    
    make_map(position_brick)
    global boom_voice
    boom_voice = SoundFile(this, 'boom.wav')
def try_boom_bots(boom_grid_pos,bots):
    for bot in bots:
        pp = bot['position']
        gridx, gridy = get_grid_idx(pp.x, pp.y)
        if (gridx, gridy) == boom_grid_pos:
            bot['state'] = 'Dead!'
def get_part_range(boom_r,x,y ,white_bricks):
    print('boom r')
    print(boom_r)
    ranges = []
    for dx , dy in [(0,1),(1,0),(0,-1),(-1,0)]:
        for i in range(1, boom_r):
            newx,newy = x+dx *i, y+dy*i
            p = (newx,newy)
            if try_hit_brick(p, white_bricks, position_object): break
            try_boom_bots(p,bots)
            ranges.append(p)
    return ranges    
    
def draw() :
    global player2
    global player1
    image(bg_img, 0, 0)
    response = c.available()
    draw_map()
    if response >0:
        stroke(255)
        inp = c.readString()
        inps = inp.split('\n')
        for inp in inps:
            if inp in ['left','right','up','down']:
                bot_walk(player1,inp)
            if inp == 'p1 bubble':
                bot_put_bubble_at_current_position(player1,bubble_time,bubble_power)
        print('from server')
        print(inp)    
    if mousePressed:
       
    
        stroke(255);
        line(pmouseX, pmouseY, mouseX, mouseY);
        data = map(str,[pmouseX, pmouseY, mouseX, mouseY])
        #c.write('line({},{},{},{})'.format(pmouseX, pmouseY, mouseX, mouseY)  )
    white_bricks = position_brick['gongfu']
    bots = [player1,player2]
    global boom_voice
    for x, y in bubble_time.keys():
        t = bubble_time.get((x, y), 10000)
        if t + exptime < millis() < t + endtime:
            if not t + exptime in boom_log:
                boom_log[t + exptime] = (x, y)        
                y_, x_ = get_grid_topleft(y, x)
                image(boom, x_, y_)
                boom_voice.play()
            yc, xc = get_grid_centre(y, x)
            
            if (x,y)  in boom_range:
                for boom_x,boom_y in boom_range[(x,y)  ]:
                    y_, x_ = get_grid_topleft(boom_y, boom_x)
                    image(boom, x_, y_)
            else:
                if (x, y) in bubble_power:
                    boom_r = bubble_power[(x, y)]
                else:
                    boom_r = player_state['obj']['power'] + 3
                ranges = [(x,y)]
                
 
                ranges += get_part_range(boom_r,x,y ,white_bricks)
                boom_range[(x,y)] = ranges
        elif millis() > t + endtime:
            del bubble_time[(x, y)]

        else:
            x2, y2 = get_grid_topleft(x, y)
            image(bubble_img, x2, y2 )
    bots = [player1,player2]        
                
    obj_map = get_inverted_obj_map(position_object)
    for bot in bots:
        pV = bot['position']
        
        obj, bot_grid_p = is_player_on_obj(pV, obj_map)
        if obj:
         
            bot_add_obj(bot, obj)
            del obj_map[bot_grid_p]
            position_object[obj].remove(bot_grid_p)
    for obj_name, positions in position_object.items():
        for x, y in positions:
            x2, y2 = get_grid_topleft(x, y)
            image(img_object[obj_name], x2, y2 - abs(int(millis()/125)%8  - 4) * 2, 40, 40 * img_object[obj_name].height / img_object[obj_name].width)
    
    p2 = get_p2_img(player2)
    bot_p = player2['position']
    bx, by = get_player_topleft(p2, bot_p.x, bot_p.y)
    image(p2, bx, by)
    
    p1 = get_p1_img(player1)
    bot_p = player1['position']
    bx, by = get_player_topleft(p1, bot_p.x, bot_p.y)
    image(p1, bx, by)
def keyPressed():
    global player2
    print("typed %s %d" % (key, keyCode))
    dir = ''
    if key == CODED:
        print(key)
        if keyCode == UP:
            dir = 'up'
            print('up')
        elif keyCode == DOWN:
            dir = 'down'
        elif keyCode == LEFT:
            dir = 'left'
        elif keyCode == RIGHT:
            dir = 'right'
    if dir !='':
        bot_walk(player2,dir)
        c.write(dir+"\n")
    local_player = player2# client is p2
    if key == 'j':
        print('put bubble')
        bot_put_bubble_at_current_position(local_player,bubble_time,bubble_power)
        c.write("p2 bubble\n")
        print(bubble_time)
    if key == 'm':
        p =  get_grid_idx(mouseX,mouseY)
        bot_put_bubble(local_player, p,bubble_time,bubble_power)
        print(bubble_time)
        c.write()